#include <graphics.h>
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include "indicat.h"

const width=200,height=70,margin=2,text_offset=10,
      bar_top=35,bar_left=10,bar_width=140,bar_height=15,
      percent_left=160,percent_top=40,percent_width=32,percent_height=15;

const msg_left=5,msg_top=55,msg_right=195,msg_bottom=65;

const back_color=CYAN,fore_color=YELLOW;

const kb_escape=0x1B;

// ------------- Graphics Indicator -------------------------
graph_indicator::graph_indicator(int _max_val,const char *title_string) :
  indicator(_max_val,title_string)  {
  graph_status = getgraphmode();
  if (graph_status==-1) return;

  int midx=getmaxx()/2,midy=getmaxy()/2;

  right=(left=midx-width/2)+width;
  bottom=(top=midy-height/2)+height;
  unsigned bufsize=imagesize(left,top,right,bottom);
  if (bufsize==0xFFFF) { graph_status=-1; return; }
  if ( !(save_graph_ptr = new char[bufsize]) ) { graph_status=-1; return; }
  current_pos=current_percent=0;
  draw();
}

graph_indicator::~graph_indicator() {
  if (graph_status==-1) return;
  putimage(left,top,save_graph_ptr,COPY_PUT);
  delete save_graph_ptr;
}

void graph_indicator::draw(void) {
  getimage(left,top,right,bottom,save_graph_ptr);
  setfillstyle(SOLID_FILL,back_color);
  bar(left,top,right,bottom);
  setcolor(fore_color);
  rectangle(left+margin,top+margin,right-margin,bottom-margin);
  settextjustify(CENTER_TEXT,CENTER_TEXT);
  outtextxy( (left+right)/2, top+text_offset, title);
  rectangle(left+bar_left,top+bar_top,
	    left+bar_left+bar_width,top+bar_top+bar_height);
}

void graph_indicator::update(int count) {
  if (graph_status==-1) return;
  int new_pos=(int) ((long)count*bar_width/max_val);
  if (new_pos!=current_pos) {
    setfillstyle(SOLID_FILL,fore_color);
    bar(left+bar_left+current_pos, top+bar_top,
	left+bar_left+new_pos,     top+bar_top+bar_height );
    current_pos=new_pos;
  }
  int new_percent = (int)((long)count*100/max_val);
  if (new_percent!=current_percent) {
    setfillstyle(SOLID_FILL,back_color);
    bar(left+percent_left, top+percent_top,
	left+percent_left+percent_width,top+percent_top+percent_height );
    setcolor(fore_color);
    settextjustify(LEFT_TEXT,TOP_TEXT);
    char tmp[5]; sprintf(tmp,"%d%%",new_percent );
    outtextxy(left+percent_left, top+percent_top, tmp);
    current_percent=new_percent;
  }
}

// --------------- Checking Indicator --------------------
check_indicator::check_indicator(int _max_val,const char *title_string) :
		 graph_indicator(_max_val,title_string) {
  left  = graph_indicator::left + msg_left;
  top   = graph_indicator::top  + msg_top;
  right = graph_indicator::left + msg_right;
  bottom= graph_indicator::top  + msg_bottom;
  draw_message();
}

int check_indicator::check() {
  if ( !kbhit() ) return 0;
  int quit=0;
  do  quit |= getch()==kb_escape;  while ( kbhit() );
  if (!quit) return 0;
  if (graph_status==-1) return 1;
  draw_check_message();
  if ( !(quit = get_yes_no()=='Y') ) draw_message();
  return quit;
}

void check_indicator::draw_message() {
  if (graph_status==-1) return;
  setfillstyle(SOLID_FILL,back_color);
  bar(left,top,right,bottom);
  settextjustify(CENTER_TEXT,CENTER_TEXT);
  setcolor(fore_color);
  outtextxy( (left+right)/2, (top+bottom)/2, "Press Esc to cancel" );
}

void check_indicator::draw_check_message() {
  if (graph_status==-1) return;
  setfillstyle(SOLID_FILL,back_color);
  bar(left,top,right,bottom);
  settextjustify(CENTER_TEXT,CENTER_TEXT);
  setcolor(fore_color);
  outtextxy( (left+right)/2, (top+bottom)/2, "Cancel ? (Y/N)" );
}

char check_indicator::get_yes_no() {
int res;
  do res=toupper(getch()); while(res!='Y' && res!='N');
  return res;
}
